home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
asmutil
/
tedasm.zip
/
TED.ASM
Wrap
Assembly Source File
|
1988-10-25
|
47KB
|
1,547 lines
;======================================================================
; TED.ASM -- The Tiny EDitor.
; PC Magazine * Tom Kihlken
;----------------------------------------------------------------------
CSEG SEGMENT
ASSUME CS:CSEG, DS:CSEG, ES:CSEG
ORG 100H ;Beginning for .COM programs
START:
JMP BEGIN
;-----------------------------------------------------------------------
; Local data area
;-----------------------------------------------------------------------
TAB EQU 9
CR EQU 13
LF EQU 10
COPYRIGHT DB CR,LF,"TED 1.0 (c) 1988 Ziff Communications Co."
DB CR,LF,"PC Magazine ",254," Tom Kihlken$",1AH
FILE_TOO_BIG DB "File too big$"
READ_ERR_MESS DB "Read error$"
MEMORY_ERROR DB "Not enough memory$"
PROMPT_STRING DB "1ABORT",0,"2UNDO",0,"3PRINT",0
DB "4MARK",0,"5CUT",0,"6PASTE",0,"7EXIT",0
DB "8DEL EOL",0,"9DEL L",0,"10UDEL L",0,0
PROMPT_LENGTH = $ - OFFSET PROMPT_STRING
VERIFY_MESS DB "Lose Changes (Y/N)?",0
SAVE_MESS DB "Save as: ",0
DOT_$$$ DB ".$$$",0
DOT_BAK DB ".BAK",0
DIRTY_BITS DB 1
NORMAL DB 07H
INVERSE DB 70H
LEFT_MARGIN DB 0
MARGIN_COUNT DB 0
INSERT_MODE DB -1
MARK_MODE DB 0
ROWS DB 23
SAVE_COLUMN DB 0
SAVE_ROW DB 0
LINE_FLAG DB 0
EVEN
NAME_POINTER DW 81H
NAME_END DW 81H
STATUS_REG DW ?
VIDEO_SEG DW 0B000H
LINE_LENGTH DW 0
UNDO_LENGTH DW 0
CUR_POSN DW 0
MARK_START DW 0FFFFH
MARK_END DW 0
MARK_HOME DW 0
TOP_OF_SCREEN DW 0
CURSOR DW 0
LAST_CHAR DW 0
COLUMNSB LABEL BYTE
COLUMNS DW ?
PASTE_SEG DW ?
PASTE_SIZE DW 0
PAGE_PROC DW ?
OLDINT24 DD ?
DISPATCH_TABLE DW OFFSET ABORT ,OFFSET UNDO ,OFFSET PRINT
DW OFFSET MARK ,OFFSET CUT ,OFFSET PASTE
DW OFFSET EXIT ,OFFSET DEL_EOL,OFFSET DEL_L
DW OFFSET UDEL_L ,OFFSET BAD_KEY,OFFSET BAD_KEY
DW OFFSET HOME ,OFFSET UP ,OFFSET PGUP
DW OFFSET BAD_KEY ,OFFSET LEFT ,OFFSET BAD_KEY
DW OFFSET RIGHT ,OFFSET BAD_KEY,OFFSET ENDD
DW OFFSET DOWN ,OFFSET PGDN ,OFFSET INSERT
DW OFFSET DEL_CHAR
; The following machine instruction removes the desnow delay. It is
; inserted into the code for EGA, VGA, and MONO displays.
NO_DESNOW = 0EBH + (OFFSET WRITE_IT - OFFSET HWAIT - 2) * 256
;-----------------------------------------------------------------------
; We start by initialize the display, then allocate memory for the file
; and paste segments. Parse the command line for a filename, if one was
; input, read in the file. Finally set the INT 23 and 24 vectors.
;-----------------------------------------------------------------------
BEGIN:
XOR AX,AX
MOV DS,AX ;Get a zero into DS
ASSUME DS:NOTHING
MOV AH,12H
MOV BL,10H ;Get EGA info
INT 10H
CMP BL,10H ;Did BL change?
JE NOT_EGA ;If not, no EGA in system
TEST BYTE PTR DS:[0487H],8 ;Is EGA active?
JNZ NOT_EGA
MOV WORD PTR CS:HWAIT,NO_DESNOW ;Get rid of desnow
MOV AX,DS:[0484H] ;Get number of rows
DEC AL ;Last row is for prompt line
MOV CS:[ROWS],AL ;Save the number of rows
NOT_EGA:
MOV AX,DS:[044AH] ;Get number of columns
MOV CS:COLUMNS,AX ;and store it
MOV AX,DS:[0463H] ;Address of display card
ADD AX,6 ;Add six to get status port
PUSH CS
POP DS
ASSUME DS:CSEG
MOV STATUS_REG,AX
CMP AX,3BAH ;Is this a MONO display?
JNE COLOR ;If not, must be a CGA
MOV WORD PTR HWAIT,NO_DESNOW ;Get rid of desnow
JMP SHORT MOVE_STACK
COLOR:
MOV VIDEO_SEG,0B800H;Segment for color card
XOR BH,BH ;Use page zero
MOV AH,8 ;Get current attribute
INT 10H
MOV NORMAL,AH ;Save the normal attribute
XOR AH,1110111B ;Flip the color bits
MOV INVERSE,AH
MOVE_STACK:
MOV BX,OFFSET NEW_STACK
MOV SP,BX ;Move the stack downward
ADD BX,15
MOV CL,4 ;Convert program size to
SHR BX,CL ; paragraphs
MOV AH,4AH ;Deallocate unused memory
INT 21H
MOV BX,1000H ;Request 64K for file segment
MOV AH,48H
INT 21H
MOV ES,AX
ASSUME ES:FILE_SEG
MOV AH,48H
INT 21H ;Request 64K for paste buffer
JNC GOT_ENOUGH ;If enough memory, continue
NOT_ENOUGH:
MOV DX,OFFSET MEMORY_ERROR
ERR_EXIT:
PUSH CS
POP DS
MOV AH,9 ;Write the error message
INT 21H ;DOS display service
JMP EXIT_TO_DOS ;Exit this program
GOT_ENOUGH:
MOV PASTE_SEG,AX ;Use this for the paste buffer
GET_FILENAME:
MOV SI,80H ;Point to parameters
MOV CL,[SI] ;Get number of characters
XOR CH,CH ;Make it a word
INC SI ;Point to first character
PUSH SI
ADD SI,CX ;Point to last character
MOV BYTE PTR [SI],0 ;Make it an ASCII string
MOV NAME_END,SI ;Save pointer to last character
POP SI ;Get back pointer to filename
CLD
JCXZ NO_FILENAME ;If no params, just exit
DEL_SPACES: LODSB ;Get character into AL
CMP AL," " ;Is it a space?
JNE FOUND_LETTER
LOOP DEL_SPACES
FOUND_LETTER:
DEC SI ;Backup pointer to first letter
MOV NAME_POINTER,SI ;Save pointer to filename
MOV DX,SI
MOV AX,3D00H ;Setup to open file
INT 21H
JC NO_FILENAME ;If we can't open, must be new file
FILE_OPENED:
PUSH ES
POP DS ;DS has file segment also
ASSUME DS:FILE_SEG
MOV BX,AX ;Get the handle into BX
XOR DX,DX ;Point to file buffer
MOV AH,3FH ;Read service
MOV CX,0FFFEH ;Read almost 64K bytes
INT 21H
MOV DI,AX ;Number of bytes read in
JNC LOOK_FOR_EOF ;If no error, take jump
MOV DX,OFFSET READ_ERR_MESS
JMP SHORT ERR_EXIT
LOOK_FOR_EOF:
CMP BYTE PTR [DI-1],1AH ;Was last char an EOF mark?
JNE NO_EOF ;If not, everything is OK
DEC DI ;Backup to last character
NO_EOF:
MOV LAST_CHAR,DI ;Save the file size
CMP CX,AX ;Did the buffer fill?
MOV DX,OFFSET FILE_TOO_BIG
JE ERR_EXIT ;If yes, it is too big
MOV AH,3EH
INT 21H ;Close the file
NO_FILENAME:
PUSH ES
PUSH ES ;Save file segment
MOV AX,3524H ;Get INT 24 vector
INT 21H
MOV WORD PTR OLDINT24,BX ;Store the offset
MOV WORD PTR OLDINT24+2,ES;And the segment
PUSH CS
POP DS
MOV DX,OFFSET NEWINT24 ;Point to new vector
MOV AX,2524H ;Now change INT 24 vector
INT 21H
MOV DX,OFFSET NEWINT23
MOV AX,2523H ;Set the INT 23 vector also
INT 21H
POP ES ;Get back file segment
POP DS
ASSUME DS:FILE_SEG, ES:FILE_SEG
CALL REDO_PROMPT ;Draw the prompt line
;-----------------------------------------------------------------------
; Here's the main loop. It updates the screen, then reads a keystroke.
;-----------------------------------------------------------------------
READ_A_KEY:
CMP MARK_MODE,0 ;Is the mark state on?
JE MARK_OFF ;If not, skip this
OR DIRTY_BITS,4 ;Refresh the current row
MOV DX,CUR_POSN
CMP SAVE_ROW,DH ;Are we on the save row?
JE SAME_ROW ;If yes, then redo the row only
MOV DIRTY_BITS,1 ;Refresh the whole screen
SAME_ROW:
MOV AX,CURSOR ;Get cursor location
MOV BX,MARK_HOME ;Get the anchor mark position
CMP AX,BX ;Moving backward in file?
JAE S1
MOV MARK_START,AX ;Switch start and end position
MOV MARK_END,BX
JMP SHORT MARK_OFF
S1:
MOV MARK_END,AX ;Store start and end marks
MOV MARK_START,BX
MARK_OFF:
MOV DX,CUR_POSN
MOV SAVE_ROW,DH
CALL SET_CURSOR ;Position the cursor
TEST DIRTY_BITS,1 ;Look at screen dirty bit
JZ SCREEN_OK ;If zero, screen is OK
MOV AH,1 ;Get keyboard status
INT 16H ;Any keys ready?
JNZ CURRENT_OK ;If yes, skip the update
CALL DISPLAY_SCREEN ;Redraw the screen
MOV DIRTY_BITS,0 ;Mark screen as OK
SCREEN_OK:
TEST DIRTY_BITS,4 ;Is the current line dirty?
JZ CURRENT_OK ;If not, take jump
CALL DISPLAY_CURRENT ;Redraw the current line
MOV DIRTY_BITS,0 ;Mark screen as OK
CURRENT_OK:
XOR AH,AH ;Read the next key
INT 16H
OR AL,AL ;Is this an extended code?
JZ EXTENDED_CODE
CMP AH,0EH ;Was it the backspace key?
JE BACK_SPACE
CALL INSERT_KEY ;Put this character in the file
JMP READ_A_KEY ;Get another key
BACK_SPACE:
CMP CURSOR,0 ;At start of file?
JE BAD_KEY ;If at start, can't backspace
CALL LEFT ;Move left one space
CALL DEL_CHAR ;And delete the character
JMP READ_A_KEY
EXTENDED_CODE:
CMP AH,84H ;Is it control PgUp?
JNE NOT_TOP
CALL TOP
JMP